home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / demos / GL / newton / models.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  11KB  |  503 lines

  1. /*
  2.  * Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /*
  18.  * Newton model building routines
  19.  * HISTORICAL NOTE: a Newton model used to be called a ``jello'', hence
  20.  * some of the `j's that appear throughout the code ...
  21.  * Yossi Friedman, July 1988
  22.  */
  23.  
  24. #include <stdio.h>
  25. #include <ctype.h>
  26. #include <math.h>
  27. #include <string.h>
  28. #include <gl.h>
  29.  
  30. #include "config.h"
  31. #include "newton.h"
  32.  
  33.  
  34. extern char *cwd();
  35.  
  36.  
  37. static char *model_fnames[MAX_MODELS], **end_model_fnames;
  38.  
  39.  
  40.  
  41. #define LINELEN 10240
  42.  
  43.  
  44. static Atom *new_atom(float, float, float);
  45. static Spring *new_spring(float, Atom *, Atom *);
  46. static Surf *new_surf(int, Atom **);
  47.  
  48.  
  49.     
  50. initialize_models()
  51. {
  52.     FILE *fp;
  53.     char line[LINELEN];
  54.     char *p, *q, *r;
  55.     int len;
  56.     int n;
  57.     
  58.     /*
  59.      * grab the list of names from model catalog
  60.      */
  61.     
  62.     if (strcmp(model_catalog, "-") == 0)
  63.     fp = stdin;
  64.     else {
  65.     fp = fopen(model_catalog, "r");
  66.     if (fp == NULL) {
  67.         fprintf(stderr, "newton: Could not open %s/%s\n", cwd(),
  68.             model_catalog);
  69.         my_exit(1);
  70.     }
  71.     }
  72.  
  73.     end_model_names = model_names;
  74.     end_model_fnames = model_fnames;
  75.  
  76.     n = 0;
  77.     while(fgets(line, LINELEN, fp) != NULL) {
  78.     for (p = line; *p && (*p != '\n') && (*p != '#');) {
  79.  
  80.         /* skip white space */
  81.         if (isspace(*p)) {
  82.         p++;
  83.         continue;
  84.         }
  85.  
  86.         /* make sure we have space */
  87.         if (++n >= MAX_MODELS) {
  88.             fprintf(stderr, "newton: too many models in the catalog.  Max is %d\n", MAX_MODELS);
  89.         my_exit(1);
  90.         }
  91.  
  92.         /* found a beginning of a name.  Figure out where it ends */
  93.         for (q = p+1; *q && (*q != '\n') && (*q != '#'); q++)
  94.         if (isspace(*q))
  95.             break;
  96.  
  97.         len = q - p;
  98.         p[len] = 0;
  99.  
  100.         *end_model_fnames = (char *) malloc(1 + len);
  101.         if (*end_model_fnames == NULL) {
  102.         fprintf(stderr, "newton: Could not malloc\n");
  103.         my_exit(1);
  104.         }
  105.         strcpy(*end_model_fnames++, p);
  106.  
  107.         if (p[len-1] == 'j' && p[len-2] == '.')
  108.         p[len-2] = '\0';
  109.         if ((r = strrchr(p, '/')) != NULL)
  110.         p = r + 1;
  111.         len = strlen(p);
  112.         *end_model_names = (char *) malloc(1 + len);
  113.         if (*end_model_names == NULL) {
  114.         fprintf(stderr, "newton: Could not malloc\n");
  115.         my_exit(1);
  116.         }
  117.         strcpy(*end_model_names++, p);
  118.  
  119.         /* advance to the next name */
  120.         p = q+1;
  121.     }
  122.     }
  123.  
  124.     if (end_model_names - model_names == 0) {
  125.     fprintf(stderr, "newton: No model description files\n");
  126.     my_exit(1);
  127.     }
  128.  
  129.     /* by default, build the first model on the list */
  130.     model_index = 0;
  131.     build_model(1);
  132. }
  133.  
  134.  
  135. build_model(int from_scratch)
  136. {
  137.     char *model_fname;
  138.     FILE *fp;
  139.     char line[LINELEN];
  140.     char *p;
  141.     int q;
  142.  
  143.     int from, to, v, n;
  144.     float old_max_k, x, y, z, k, f;
  145.     Atom *surf_buf[MAX_SURF_N];
  146.  
  147.     free_atoms();
  148.     free_springs();
  149.     free_surfs();
  150.  
  151.     model_fname = model_fnames[model_index];
  152.     fp = fopen(model_fname, "r");
  153.     if (fp == NULL) {
  154.     fprintf(stderr, "newton: Could not open ");
  155.     if (model_fname[0] != '/')
  156.         fprintf(stderr, "%s/", cwd());
  157.     fprintf(stderr, "%s\n", model_fname);
  158.     my_exit(1);
  159.     }
  160.  
  161.     if (from_scratch) {
  162.  
  163.     /* set the default material properites for the model */
  164.     model_material_size = default_model_material_size;
  165.     memcpy(model_material, default_model_material,
  166.            model_material_size * sizeof(float));
  167.  
  168.     /* set the default draw functions for the model */
  169.     draw_model = DRAW_MODEL_DEFAULT;
  170.     springs_too = SPRINGS_TOO_DEFAULT;
  171.     alpha_blended = ALPHA_BLENDED_DEFAULT;
  172.     }
  173.  
  174.     old_max_k = max_k;
  175.     max_k = -1500.;        /* minus infinity */
  176.     
  177.     while (fgets(line, LINELEN, fp) != NULL)
  178.     switch (line[0]) {
  179.       case '\n':
  180.       case '#':
  181.         continue;
  182.  
  183.       case 'a':
  184.         sscanf(line + 1, "%f %f %f", &x, &y, &z);
  185.         new_atom(x, y, z);
  186.         break;
  187.  
  188.       case 'c':
  189.         sscanf(line + 1, "%f %d %d", &k, &from, &to);
  190.         (void) new_spring(k, &model_atoms[from], &model_atoms[to]);
  191.         if (max_k < k)
  192.         max_k = k;
  193.         break;
  194.  
  195.       case 's':
  196.         p = line + 1;
  197.         for (n = 0; sscanf(p, "%d%n", &v, &q) == 1; p += q) {
  198.         if (n == MAX_SURF_N) {
  199.             fprintf(stderr, "newton: %s: Surface too big\n", model_fname);
  200.             my_exit(1);
  201.         }
  202.         surf_buf[n++] = &model_atoms[v];
  203.         }
  204.         (void) new_surf(n, surf_buf);
  205.         break;
  206.  
  207.       case 'M':
  208.         p = line + 1;
  209.         for (n = 0; sscanf(p, "%f%n", &f, &q) == 1; p += q) {
  210.         if (n == MAX_LIGHTING_SIZE) {
  211.             fprintf(stderr, "newton: %s: Material too big\n", model_fname);
  212.             my_exit(1);
  213.         }
  214.         model_material[n++] = f;
  215.         }
  216.         model_material_size = n;
  217.         break;
  218.         
  219.       case 'S':
  220.         draw_model = draw_smooth_surfs;
  221.         break;
  222.  
  223.       case 'F':
  224.         draw_model = draw_flat_surfs;
  225.         break;
  226.  
  227.       case 'B':
  228.         if (from_scratch && (mode != COLOR_MAP)) {
  229.             mode = COLOR_MAP;
  230.             cmode();
  231.             gconfig();
  232.         }
  233.         break;
  234.         
  235.       default:
  236.         fprintf(stderr, "newton: %s: Syntax error\n", model_fname);
  237.         my_exit(1);
  238.     }
  239.     
  240.     fclose(fp);
  241.  
  242. #ifdef MP
  243.  
  244.     {
  245.     /*
  246.      * divide the atoms, springs and surfs lists
  247.      */
  248.     int i;
  249.     int n_atoms  = (end_model_atoms TOTAL - model_atoms) / nproc;
  250.     int n_springs  = (end_model_springs TOTAL - model_springs) / nproc;
  251.     int n_surfs  = (end_model_surfs TOTAL - model_surfs) / nproc;
  252.  
  253.     end_model_atoms MASTER = model_atoms + n_atoms;
  254.     end_model_springs MASTER = model_springs + n_springs;
  255.     end_model_surfs MASTER = model_surfs + n_surfs;
  256.  
  257.     for (i = 1; i < nproc - 1; i++) {
  258.         end_model_atoms[i] = end_model_atoms[i-1] + n_atoms;
  259.         end_model_springs[i] = end_model_springs[i-1] + n_springs;
  260.         end_model_surfs[i] = end_model_surfs[i-1] + n_surfs;
  261.     }
  262.     }
  263.  
  264. #endif /* MP */
  265.  
  266.     /*
  267.      * this is necessary in order to set dt and redraw the K slider
  268.      */
  269.     if (from_scratch)
  270.  
  271. #if ECLIPSE || CLOVER1            /* the slow machines */
  272.     set_default_k(max_k / 2.0);
  273. #else /* ECLIPSE || CLOVER1 */
  274.     set_default_k(max_k);
  275. #endif /* ECLIPSE || CLOVER1 */
  276.  
  277.     else
  278.     set_k(old_max_k);
  279.  
  280.     /*
  281.      * set the model material
  282.      */
  283.     if (from_scratch) {
  284.  
  285. #ifndef HAS_BLENDING
  286.  
  287.     /* kludge to avoid crashes due to alpha blending */
  288.     if (model_material[0] == (float)ALPHA)
  289.         lmdef(DEFMATERIAL,
  290.           MODEL_MATERIAL_INDEX,
  291.           model_material_size - 2,
  292.           model_material + 2);
  293.     else
  294.  
  295. #endif /* HAS_BLENDING */
  296.  
  297.     lmdef(DEFMATERIAL,
  298.           MODEL_MATERIAL_INDEX,
  299.           model_material_size,
  300.           model_material);
  301.     }
  302. }
  303.  
  304.  
  305. /*
  306.  * rotate the model in the ROOM coordinate system
  307.  * around a VIEWING axis
  308.  */
  309. rotate_model(Angle alpha, char axis)
  310. {
  311.     /*
  312.      * the formula is:
  313.      *   v R = v M rot M_inv,
  314.      * where rot is the rotation matrix (in the viewing system) around the
  315.      * viewing axis.
  316.      */
  317.     pushmatrix();
  318.       loadmatrix(M_inv);
  319.       rotate(alpha, axis);
  320.       multmatrix(M);
  321.       getmatrix(R);
  322.     popmatrix();
  323.     
  324.     SLAVE_FUNC(DO_ROTATE_MODEL);
  325.     do_rotate_model(model_atoms, end_model_atoms MASTER);
  326.     WAIT_FOR_SLAVE();
  327. }
  328.  
  329. do_rotate_model(Atom *start, Atom *finish)
  330. {
  331.     Atom *ap;
  332.     float ov[3], *v;
  333.     
  334.     for (ap = start; ap < finish; ap++) {
  335.     v = ap->pos;
  336.     ov[X] = v[X]; ov[Y] = v[Y]; ov[Z] = v[Z];
  337.     apply(v, ov, R);
  338.     }
  339. }
  340.  
  341.  
  342. /*
  343.  * Data Structure Stuff
  344.  */
  345.  
  346. free_atoms()
  347. {
  348.  
  349. #ifdef MP
  350.  
  351.     {
  352.     int i;
  353.     
  354.     for (i = 0; i < nproc; i++)
  355.         end_model_atoms[i] = model_atoms;
  356.     }
  357.  
  358. #else /* MP */
  359.  
  360.     end_model_atoms = model_atoms;
  361.  
  362. #endif /* MP */
  363.  
  364. }
  365.  
  366. static Atom *
  367. new_atom(float x, float y, float z)
  368. {
  369.     if (end_model_atoms TOTAL == model_atoms + MAX_ATOMS) {
  370.     fprintf(stderr, "newton: %s: Too many atoms\n", model_names[model_index]);
  371.     my_exit(1);
  372.     }
  373.  
  374.     end_model_atoms TOTAL ->pos[X] = x;
  375.     end_model_atoms TOTAL ->pos[Y] = y;
  376.     end_model_atoms TOTAL ->pos[Z] = z;
  377.     
  378.     end_model_atoms TOTAL ->vel[X] = 0.0;
  379.     end_model_atoms TOTAL ->vel[Y] = 0.0;
  380.     end_model_atoms TOTAL ->vel[Z] = 0.0;
  381.     
  382. #ifdef MP
  383.  
  384.     {
  385.     int i;
  386.  
  387.     for (i = 0; i < nproc; i++)
  388.         end_model_atoms TOTAL ->acc[i][X] =
  389.         end_model_atoms TOTAL ->acc[i][Y] =
  390.         end_model_atoms TOTAL ->acc[i][Z] = 0.;
  391.     }
  392.  
  393. #else /* MP */
  394.  
  395.     end_model_atoms TOTAL ->acc[X] =
  396.     end_model_atoms TOTAL ->acc[Y] =
  397.     end_model_atoms TOTAL ->acc[Z] = 0.0;
  398.  
  399. #endif /* MP */
  400.     
  401.     return(end_model_atoms TOTAL ++);
  402. }
  403.  
  404.  
  405. free_springs()
  406. {
  407.  
  408. #ifdef MP
  409.  
  410.     {
  411.     int i;
  412.     
  413.     for (i = 0; i < nproc; i++)
  414.         end_model_springs[i] = model_springs;
  415.     }
  416.  
  417. #else /* MP */
  418.  
  419.     end_model_springs = model_springs;
  420.  
  421. #endif /* MP */
  422.  
  423. }
  424.  
  425. static Spring *
  426. new_spring(float k, Atom *a1, Atom *a2)
  427. {
  428.     float r0[3];
  429.     
  430.     if (end_model_springs TOTAL == model_springs + MAX_SPRING) {
  431.     fprintf(stderr, "newton: %s: Too many springs\n", model_names[model_index]);
  432.     my_exit(1);
  433.     }
  434.  
  435.     end_model_springs TOTAL ->k = k;
  436.     end_model_springs TOTAL ->from = a1;
  437.     end_model_springs TOTAL ->to = a2;
  438.  
  439.     vec_op(r0, a1->pos, -, a2->pos);
  440.     end_model_springs TOTAL ->r0 = sqrt(r0[X]*r0[X] + r0[Y]*r0[Y] + r0[Z]*r0[Z]);
  441.  
  442.     return(end_model_springs TOTAL ++);
  443. }
  444.  
  445.  
  446. free_surfs()
  447. {
  448.     Surf *sp;
  449.     
  450.     for (sp = model_surfs; sp < end_model_surfs TOTAL; sp++) {
  451.     free(sp->vert);
  452.     free(sp->norm);
  453.     }
  454.     
  455. #ifdef MP
  456.  
  457.     {
  458.     int i;
  459.     
  460.     for (i = 0; i < nproc; i++)
  461.         end_model_surfs[i] = model_surfs;
  462.     }
  463.  
  464. #else /* MP */
  465.  
  466.     end_model_surfs = model_surfs;
  467.  
  468. #endif /* MP */
  469.  
  470. }
  471.  
  472. static Surf *
  473. new_surf(int n, Atom **vert)
  474. {
  475.     Atom **ap;
  476.     
  477.     if (end_model_surfs TOTAL == model_surfs + MAX_SURF) {
  478.     fprintf(stderr, "newton: %s: Too many surfs\n", model_names[model_index]);
  479.     my_exit(1);
  480.     }
  481.  
  482.     if (n < 3) {
  483.     fprintf(stderr, "newton: %s: Surf too small\n", model_names[model_index]);
  484.     my_exit(1);
  485.     }
  486.  
  487.     end_model_surfs TOTAL ->n = n;
  488.     end_model_surfs TOTAL ->vert = (Atom **) malloc(n * sizeof(Atom *));
  489.     if (end_model_surfs TOTAL ->vert == NULL) {
  490.     fprintf(stderr, "newton: %s: Could not malloc\n", model_names[model_index]);
  491.     my_exit(1);
  492.     }
  493.     for (ap = end_model_surfs TOTAL ->vert; n--; *ap++ = *vert++)
  494.     ;
  495.     end_model_surfs TOTAL ->norm = (float *) malloc(end_model_surfs TOTAL ->n * 4 * sizeof(float));
  496.     if (end_model_surfs TOTAL ->norm == NULL) {
  497.     fprintf(stderr, "newton: %s: Could not malloc\n", model_names[model_index]);
  498.     my_exit(1);
  499.     }
  500.  
  501.     return(end_model_surfs TOTAL ++);
  502. }
  503.